package com.yiyi.controller;

import com.yiyi.entity.Exam;
import com.yiyi.form.AddExamForm;
import com.yiyi.service.AnswerService;
import com.yiyi.service.ChoiceService;
import com.yiyi.service.ExamQuestionService;
import com.yiyi.service.ExamService;
import com.yiyi.util.ExamRedisUtil;
import com.yiyi.vo.ExamVO;
import com.yiyi.vo.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @author yiyi
 * @date 2021/5/30
 *
 * 1、创建新试卷
 * 2、根据职位id获取一张试卷
 * 3、根据试卷id获取试卷
 * 4、分页获取试卷
 * 5、删除试卷
 */
@RestController
@RequestMapping("/exam")
@Api(tags = {"试卷操作接口"})
public class ExamController {

    @Autowired
    private ExamService examService;
    @Autowired
    private ExamQuestionService examQuestionService;
    @Autowired
    private ChoiceService choiceService;
    @Autowired
    private AnswerService answerService;
    @Autowired
    private ExamRedisUtil examRedisUtil;

    /**
     * 创建新试卷
     *
     * @param addExamForm
     * @return
     * */
    @PostMapping("/save")
    @ApiOperation(value = "新增试卷")
    public R save(@RequestBody AddExamForm addExamForm) {
        // 先保存试卷主体内容
        Exam exam = new Exam();
        exam.setExamId(String.valueOf(System.currentTimeMillis()));
        exam.setPositionId(addExamForm.getPositionId());
        exam.setExamTitle(addExamForm.getExamTitle());
        exam.setExamGrade(addExamForm.getExamGrade());
        exam.setExamTime(addExamForm.getExamTime());
        examService.save(exam);
        // 再保存试卷题目
        examQuestionService.saveNewExam(exam.getExamId(), 0, addExamForm.getChoiceIds());
        examQuestionService.saveNewExam(exam.getExamId(), 1, addExamForm.getAnswerIds());

        return R.ok();
    }

    /**
     * 使用redis优化取试卷功能，减少用户等待时间。
     * 在用户点击按键进入填写表单页面时，即触发此接口，把试卷内容暂存在redis中，有效期为10分钟
     * 后续进入考试页面时可直接在redis中获取数据，减少等待时间
     *
     * @param positionId
     * @return
     * */
    @GetMapping("/prepareExam/{positionId}")
    @ApiOperation(value = "准备试卷")
    public R prepareExam(@PathVariable("positionId") String positionId) {
        if (examRedisUtil.hasExam(positionId)) {
            return R.ok();
        }
        // 首先获取试卷大纲内容
        Exam exam = examService.findByPositionId(positionId);
        examRedisUtil.setExam(exam);
        // 再获取题目id列表
        List<String> choiceIds = examQuestionService.findByExamId(exam.getExamId(), 0);
        List<String> answerIds = examQuestionService.findByExamId(exam.getExamId(), 1);
        examRedisUtil.setList(exam.getPositionId(), 0, choiceIds);
        examRedisUtil.setList(exam.getPositionId(), 1, answerIds);
        return R.ok();
    }

    /**
     * 根据职位id获取试卷
     * 使用redis优化该方法
     *
     * @param positionId
     * @return
     * */
    @GetMapping("/findByPositionId/{positionId}")
    @ApiOperation(value = "根据职位id获取试卷")
    public R findByPositionId(@PathVariable("positionId") String positionId) {
        ExamVO examVO = new ExamVO();
        List<String> choiceIds;
        List<String> answerIds;
        // 首先判断缓存中是否保存该试卷信息
        if (examRedisUtil.hasExam(positionId)) {
            // 若存在则直接在redis中获取
            examVO = examRedisUtil.getExam(positionId);
            choiceIds = examRedisUtil.getList(positionId, 0);
            answerIds = examRedisUtil.getList(positionId, 1);
        } else {
            // 否则调用服务从数据库中获取
            // 首先获取试卷大纲内容
            Exam exam = examService.findByPositionId(positionId);
            // 试卷不存在直接返回失败
            if (exam == null) {
                return R.fail();
            }
            examVO.setExamId(exam.getExamId());
            examVO.setExamTitle(exam.getExamTitle());
            examVO.setExamTime(exam.getExamTime());
            examVO.setExamGrade(exam.getExamGrade());
            // 再获取题目id列表
            choiceIds = examQuestionService.findByExamId(exam.getExamId(), 0);
            answerIds = examQuestionService.findByExamId(exam.getExamId(), 1);
        }
        // 最后获取题目详情，试卷有可能会出现某个题型数量为空的情况
        if (choiceIds.size() != 0) {
            examVO.setChoices(choiceService.findListByIds(choiceIds));
        }
        if (answerIds.size() != 0) {
            examVO.setAnswers(answerService.findListByIds(answerIds));
        }
        return R.ok(examVO);
    }

    /**
     * 根据id获取试卷
     *
     * @param id
     * @return
     * */
    @GetMapping("/findById/{id}")
    @ApiOperation(value = "根据id获取试卷")
    public R findById(@PathVariable("id") String id) {
        ExamVO examVO = new ExamVO();
        // 获取试卷主体内容
        Exam exam = examService.findById(id);
        examVO.setExamId(exam.getExamId());
        examVO.setExamTitle(exam.getExamTitle());
        examVO.setExamGrade(exam.getExamGrade());
        examVO.setExamTime(exam.getExamTime());
        // 获取题目详情
        List<String> choiceIds = examQuestionService.findByExamId(id, 0);
        List<String> answerIds = examQuestionService.findByExamId(id, 1);
        // 最后获取题目详情，试卷有可能会出现某个题型数量为空的情况
        if (choiceIds.size() != 0) {
            examVO.setChoices(choiceService.findListByIds(choiceIds));
        }
        if (answerIds.size() != 0) {
            examVO.setAnswers(answerService.findListByIds(answerIds));
        }
        return R.ok(examVO);
    }

    /**
     * 分页查询试卷信息
     *
     * @param current
     * @param size
     * @return
     * */
    @GetMapping("/findByPage/{current}/{size}")
    @ApiOperation(value = "分页查询试卷信息")
    public R findByPage(@PathVariable("current") Integer current, @PathVariable("size") Integer size) {
        return R.ok(examService.findByPage(current, size));
    }

    /**
     * 删除试卷信息
     *
     * @param id
     * @return
     * */
    @DeleteMapping("/deleteById/{id}")
    @ApiOperation(value = "删除试卷信息")
    public R deleteById(@PathVariable("id") String id) {
        // 先删除试卷主体信息
        examService.deleteById(id);
        // 再删除试卷题目对应信息
        examQuestionService.deleteByExamId(id);
        return R.ok();
    }
}
